using System;
using System.Collections.Generic;
using System.Windows.Forms;
using RideMe.Core;
using System.Runtime.InteropServices;
using System.Threading;

namespace RideMe.Presentation
{
    static class Program
    {

        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);

#if !DEBUG
            Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
            AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
#endif

            MainForm mainForm = new MainForm();

            // We only want to load the last project
            // if the app isn't already running. This
            // way two instances of the app won't start
            // with the same project loaded. Makes sense, right?
            using (Mutex mutex = new Mutex(false, Application.ProductName))
            {
                bool running = !mutex.WaitOne(0, false);
                if (!running)
                {

                    if (Options.Instance.LoadLastProjectAtStartUp)
                    {
                        if ((Options.Instance.LastLoadedProjectPath != null) && (Options.Instance.LastLoadedProjectPath.Length > 0))
                        {
                            try
                            {
                                ProjectService.ProjectPath = Options.Instance.LastLoadedProjectPath;
                                LoadPreviouslyOpenedFiles();
                            }
                            catch (ArgumentException)
                            { }
                        }
                    }
                }

                Application.Run(mainForm);
            }

        }

        /// <summary>
        /// Handles the unhandled exceptions.
        /// </summary>
        /// <param name="exception"></param>
        private static void HandleUnhandledException(Exception exception)
        {
            try
            {
                ExceptionManagement.ExceptionPublisher.PublishException(exception);
                ExceptionManagement.ExceptionPublisher.ShowExceptionDialog(exception);
            }
            catch { }
        }

        /// <summary>
        /// Handles the UnhandledException event of the CurrentDomain control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="T:System.UnhandledExceptionEventArgs"/> instance containing the event data.</param>
        private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            Exception exception = e.ExceptionObject as Exception;
            if (exception != null)
            {
                HandleUnhandledException(exception);
            }
        }

        /// <summary>
        /// Handles the ThreadException event of the Application control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="T:System.Threading.ThreadExceptionEventArgs"/> instance containing the event data.</param>
        private static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
        {
            if (e.Exception != null)
            {
                HandleUnhandledException(e.Exception);
            }
        }

        /// <summary>
        /// Loads any previously opened files.
        /// </summary>
        private static void LoadPreviouslyOpenedFiles()
        {
            if ((Options.Instance.PreviouslyOpenedFiles != null) && (Options.Instance.PreviouslyOpenedFiles.Count > 0))
            {
                foreach (string file in Options.Instance.PreviouslyOpenedFiles)
                {
                    ProjectService.AddOpenFile(file);
                }
            }
        }
    }
}
